namespace EFS.Common
{
	/// Common.Verify
	public class Verify
	{
		/** Check if the parameter variable is null
		*\param variable The value to check.
		*\param variableName The name of the variable being checked.
		*/
		public static void Reference(System.Object variable, System.String variableName)
		{
			// check variable reference
			if (null == variable)
			{
				// variable is null, assert or throw exception
#if ASSERT
					System.Diagnostics.Debug.Assert(false, variableName);
#else
				throw new System.Exception(variableName);
#endif
			}
		}

		/** Check if the parameter variable is null
		*\param variable The value to check.
		*\param variableName The name of the variable being checked.
		*/
		public static System.Boolean Guid(System.Guid? variable)
		{
			// check variable reference
			return null != variable && variable.Value != System.Guid.Empty;
		}

		/** Check if the parameter variable is null
		*\param variable The value to check.
		*\param variableName The name of the variable being checked.
		*/
		public static System.Boolean Guid(System.Guid variable)
		{
			// check variable reference
			return variable != System.Guid.Empty;
		}

		/** Check if the parameter variable is null
		*\param variable The value to check.
		*\param variableName The name of the variable being checked.
		*/
		public static void Guid(System.Guid variable, System.String variableName)
		{
			// check variable reference
			if (variable == System.Guid.Empty)
			{
				// variable is null, assert or throw exception
#if ASSERT
					System.Diagnostics.Debug.Assert(false, variableName);
#else
				throw new System.Exception(variableName);
#endif
			}
		}

		/// <summary>
		/// check if string is guid
		/// </summary>
		/// <param name="quoteGuidStr"></param>
		/// <returns></returns>
		public static System.Boolean Guid(System.String quoteGuidStr)
		{
			// quote id
			try
			{
				System.Guid quoteGuid = new System.Guid(quoteGuidStr);
			}
			catch (System.Exception)
			{
				// no guid
				return false;
			}

			// is guid
			return true;
		}


		/** Check if the parameter "variable" is an empty System.String.
		*\param variable The value to check.
		*/
		public static System.Boolean String(System.String variable)
		{
			// check reference and variable length
			return ((null != variable) && (variable.Length > 0));
		}

		/** Check if the parameter "variable" is an empty System.String.
		*\param variable The value to check.
		*\param variableName The name of the variable being checked.
		*	# if ASSERT deffined the method causes an assertion failed
		*	# else the method throws System.Exception(variableName)
		*/
		public static void String(System.String variable, System.String variableName)
		{
			// check reference and variable length
			if (null == variable || variable.Length == 0)
			{
#if ASSERT
					System.Diagnostics.Debug.Assert(false, variableName);
#else
				throw new System.Exception(variableName);
#endif
			}
		}

		/** Check if the parameter "variable" is a number (>=0).
		*\param variable The value to check.
		*\param variableName The name of the variable being checked.
		*/
		public static void Number(System.Int32 variable, System.String variableName)
		{
			// check number
			if (variable < 0)
			{
#if ASSERT
					System.Diagnostics.Debug.Assert(false, variableName);
#else
				throw new System.Exception(variableName);
#endif
			}
		}

		/** Check if the parameter "variable" is a positive number (>0).
		*\param variable The value to check.
		*\param variableName The name of the variable being checked.
		*/
		public static void PositiveNumber(System.Int32 variable, System.String variableName)
		{
			// check number
			if (variable <= 0)
			{
#if ASSERT
					System.Diagnostics.Debug.Assert(false, variableName);
#else
				throw new System.Exception(variableName);
#endif
			}
		}

		/** Check if the parameter "variable" is in min - max range
		*\param variable The value to check.
		*\param variableName The name of the variable being checked.
		*/
		public static void Range(System.Int32 variable, System.Int32 min, System.Int32 max, System.String variableName)
		{
			// check number
			if (variable < min || variable > max)
			{
#if ASSERT
					System.Diagnostics.Debug.Assert(false, variableName);
#else
				throw new System.Exception(variableName);
#endif
			}
		}

		/** Check if the parameter "variable" is in min - max absolute range
		*\param variable The value to check.
		*\param variableName The name of the variable being checked.
		*/
		public static void AbsoluteRange(System.Int32 variable, System.Int32 min, System.Int32 max, System.String variableName)
		{
			// check number
			if (variable <= min || variable >= max)
			{
#if ASSERT
					System.Diagnostics.Debug.Assert(false, variableName);
#else
				throw new System.Exception(variableName);
#endif
			}
		}

		/** Checks parameter "variable" for zero length array
		*\param variable Array to check.
		*/
		public static System.Boolean Array(System.Object[] variable)
		{
			// check reference and length
			return ((null != variable) && (variable.Length > 0));
		}

		/** Checks parameter "variable" for zero length byte array
		*\param variable Array to check.
		*\param variableName The name of the variable being checked.
		*	# if ASSERT deffined the method causes an assertion failed
		*	# else the method throws System.Exception(variableName)
		*/
		public static void Array(System.Object[] variable, System.String variableName)
		{
			// check reference and bytes length
			if (null == variable || variable.Length == 0)
			{
#if ASSERT
					System.Diagnostics.Debug.Assert(false, variableName);
#else
				throw new System.Exception(variableName);
#endif
			}
		}

		/** Check parameter "variable" to determine if it matches the parameter "type".
		*\param variable The value to check.
		*\param type The type expected of \param "variable".
		*	# if ASSERT deffined the method causes an assertion failed
		*	# else the method throws System.Exception("Type mismatch found while checking expected type")
		*/
		public static void ExpectedType(System.Object variable, System.Type type)
		{
			// check references
			Reference(variable, "variable");
			Reference(type, "type");

			// check type
			if (!type.IsAssignableFrom(variable.GetType()))
			{
#if ASSERT
					System.Diagnostics.Debug.Assert(false, "Type mismatch found while checking expected type");
#else
				throw new System.Exception("Type mismatch found while checking expected type");
#endif
			}
		}

		/** Check parameter "variable" to determine sub-type of the parameter "type".
		*\param variable The type to check.
		*\param type The type expected of \param "variable".
		*	# if ASSERT deffined the method causes an assertion failed
		*	# else the method throws System.Exception("Type mismatch found while checking expected type")
		*/
		public static void ExpectedType(System.Type variable, System.Type type)
		{
			// check references
			Reference(variable, "variable");
			Reference(type, "type");

			// check type
			if (!type.IsAssignableFrom(variable))
			{
#if ASSERT
				System.Diagnostics.Debug.Assert(false, "Type mismatch found while checking expected sub-type");
#else
				throw new System.Exception("Type mismatch found while checking expected sub-type");
#endif
			}
		}

		/** Check parameter "condition" for true or false 
		*\param condition The value to check.
		*\param mesasge for false cafe
		*	# if ASSERT deffined the method causes an assertion failed
		*	# else the method throws System.Exception(message)
		*/
		public static void Condition(System.Boolean condition, System.String message)
		{
			// check references
			String(message, "message");

			// check condition
			if (!condition)
			{
#if ASSERT
				System.Diagnostics.Debug.Assert(false, message);
#else
				throw new System.Exception(message);
#endif
			}
		}
	}
}
